package com.ys.erp.stage_mall_service.service;


import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.ys.erp.common.enums.EnableEnum;
import com.ys.erp.common.enums.old.StatusOldEnum;
import com.ys.erp.common.util.MoneyUtil;
import com.ys.erp.common.util.YsThread;
import com.ys.erp.entity.data.bean.*;
import com.ys.erp.entity.service.*;
import com.ys.erp.entity.service.impl.IOrderServiceImpl;
import com.ys.erp.framework.bean.dto.StageEmpDTO;
import com.ys.erp.framework.exception.YsException;
import com.ys.erp.stage_mall_service.bean.condition.HomeGroupAreaCondition;
import com.ys.erp.stage_mall_service.bean.vo.HomeGroupAreaInfoVO;
import com.ys.erp.stage_mall_service.bean.vo.HomeGroupAreaVO;
import lombok.RequiredArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author minamiyama
 * @date 2025/5/19 11:34
 */
@RequiredArgsConstructor
@Service
public class HomeGroupAreaService {

    private final IMallHomeGroupAreaService iMallHomeGroupAreaService;
    private final IMallHomeGroupPutUpAreaService iMallHomeGroupPutUpAreaService;
    private final IMallHomeGoodsCateService iMallHomeGoodsCateService;
    private final IMallHomeGoodsService iMallHomeGroupGoodsService;
    private final IGoodsService iGoodsService;
    private final IGoodsSpecsService iGoodsSpecsService;
    private final IGoodsBrandService iGoodsBrandService;
    private final IOrderServiceImpl iOrderService;
    private final IOrderGoodsService iOrderGoodsService;
    private final IMallHomeGoodsService iMallHomeGoodsService;

    /**
     * 添加或更新首页聚合区域信息
     *
     * @param con    包含要添加或更新的聚合区域信息的条件对象
     * @param empDTO 当前操作员工的信息
     *               此方法首先检查条件对象中是否包含ID如果ID为空，则创建新的聚合区域；
     *               否则，更新现有聚合区域信息然后，根据条件对象中的信息更新或添加
     *               商品、分类和推荐区域信息
     */
    @Transactional(rollbackFor = Exception.class)
    public void addHomeGroupArea(HomeGroupAreaCondition.AddOrUpdateHomeGroupAreaCon con, StageEmpDTO empDTO) {
        ArrayList<MallHomeGoods> groupGoods = new ArrayList<>();
        List<MallHomeGoodsCate> goodsCateList = new ArrayList<>();
        // 检查条件对象中的ID，如果为空，则表示需要添加新的聚合区域
        if (Objects.isNull(con.getId())) {
            MallHomeGroupArea groupArea = new MallHomeGroupArea();
            groupArea.setNo("groupArea" + UUID.randomUUID());
            BeanUtils.copyProperties(con, groupArea);
            groupArea.setImportRuleJson(JSONObject.toJSONString(con.getImportRule()));
            groupArea.setEmpName(empDTO.getRealName());
            groupArea.setEmpPhone(empDTO.getPhone());
            groupArea.setEmpId(empDTO.getId());
            groupArea.setType(con.getType());
            iMallHomeGroupAreaService.save(groupArea);
            addPutUpArea(con.getPutUpAreaList(), groupArea.getNo(), groupGoods);
            saveCate(con, groupArea.getNo(), goodsCateList);
            addGoods(goodsCateList, con, groupGoods, groupArea.getNo());
            return;
        }

        // 根据条件对象中的ID获取现有的聚合区域信息，如果不存在，则抛出异常
        MallHomeGroupArea groupArea = iMallHomeGroupAreaService.getById(con.getId());
        if (Objects.isNull(groupArea)) {
            throw new YsException(-1, "源数据不存在，无法修改");
        }
        BeanUtils.copyProperties(con, groupArea);
        groupArea.setImportRuleJson(JSONObject.toJSONString(con.getImportRule()));
        groupArea.setEmpName(empDTO.getRealName());
        groupArea.setEmpPhone(empDTO.getPhone());
        groupArea.setEmpId(empDTO.getId());
        groupArea.setType(con.getType());
        iMallHomeGroupAreaService.updateById(groupArea);
        // 删除现有的聚合区商品信息，以便后续重新添加
        removeOther(groupArea);

        // 添加新的推荐区域、分类和商品信息
        addPutUpArea(con.getPutUpAreaList(), groupArea.getNo(), groupGoods);
        saveCate(con, groupArea.getNo(), goodsCateList);
        addGoods(goodsCateList, con, groupGoods, groupArea.getNo());
    }


    @Transactional(rollbackFor = Exception.class)
    public void delHomeGroupArea(Long id, StageEmpDTO empDTO) {
        MallHomeGroupArea groupArea = iMallHomeGroupAreaService.getById(id);
        if (Objects.isNull(groupArea)) {
            throw new YsException(-1, "源数据不存在，无法修改");
        }
        removeOther(groupArea);
        iMallHomeGroupAreaService.removeById(id);

    }


    /**
     * 更新聚合区域状态
     *
     * @param id     聚合区域ID
     * @param empDTO 操作人
     */
    public void updateHomeGroupAreaStatus(Long id, StageEmpDTO empDTO) {
        MallHomeGroupArea groupArea = iMallHomeGroupAreaService.getById(id);
        if (Objects.isNull(groupArea)) {
            throw new YsException(-1, "源数据不存在，无法修改");
        }
        if (groupArea.getStatus() == EnableEnum.YES.getEnable()) {
            groupArea.setStatus(EnableEnum.NO.getEnable());
            groupArea.setEmpName(empDTO.getRealName());
            groupArea.setEmpPhone(empDTO.getPhone());
            groupArea.setEmpId(empDTO.getId());
            iMallHomeGroupAreaService.updateById(groupArea);
            return;
        }
        QueryWrapper<MallHomeGroupArea> areaQueryWrapper = new QueryWrapper<>();
        areaQueryWrapper.lambda().eq(MallHomeGroupArea::getStatus, EnableEnum.YES.getEnable());
        areaQueryWrapper.lambda().eq(MallHomeGroupArea::getType, groupArea.getType());
        long count = iMallHomeGroupAreaService.count(areaQueryWrapper);
        if (count >= 1) {
            throw new YsException(-1, "该聚合区域已启用，请勿重复启用");
        }
        groupArea.setStatus(EnableEnum.YES.getEnable());
        groupArea.setEmpName(empDTO.getRealName());
        groupArea.setEmpPhone(empDTO.getPhone());
        groupArea.setEmpId(empDTO.getId());
        iMallHomeGroupAreaService.updateById(groupArea);
    }

    /**
     * 获取聚合区详细信息
     *
     * @param id 聚合区id
     * @return 返回对象
     */
    public HomeGroupAreaInfoVO getHomeGroupAreaInfo(Long id) {
        //定义返回
        HomeGroupAreaInfoVO vo = new HomeGroupAreaInfoVO();
        MallHomeGroupArea groupArea = iMallHomeGroupAreaService.getById(id);
        if (Objects.isNull(groupArea)) {
            throw new YsException(-1, "源数据不存在，查询错误");
        }
        vo.setType(groupArea.getType());
        BeanUtils.copyProperties(groupArea, vo);
        // 查询所有推荐区
        QueryWrapper<MallHomeGroupPutUpArea> putUpQw = new QueryWrapper<>();
        putUpQw.lambda().eq(MallHomeGroupPutUpArea::getHomeGrepAreaNo, groupArea.getNo());
        List<MallHomeGroupPutUpArea> putUpAreaList = iMallHomeGroupPutUpAreaService.list(putUpQw);
        if (CollectionUtils.isNotEmpty(putUpAreaList)) {
            List<String> putUpAreaNoList = putUpAreaList.stream().map(MallHomeGroupPutUpArea::getNo).toList();
            //查询推荐区下的所有商品
            QueryWrapper<MallHomeGoods> putUpGoodsQw = new QueryWrapper<>();
            putUpGoodsQw.lambda().in(MallHomeGoods::getPutUpAreaNo, putUpAreaNoList);
            List<MallHomeGoods> putUpGoodsList = iMallHomeGroupGoodsService.list(putUpGoodsQw);
            Map<String, List<MallHomeGoods>> putUpGoodsMap = putUpGoodsList.stream().collect(Collectors.groupingBy(MallHomeGoods::getPutUpAreaNo));
            //创建数据推荐区的返回集合
            ArrayList<HomeGroupAreaInfoVO.PutUpArea> putUpAreas = new ArrayList<>();
            for (MallHomeGroupPutUpArea putUpArea : putUpAreaList) {
                HomeGroupAreaInfoVO.PutUpArea putUpVo = new HomeGroupAreaInfoVO.PutUpArea();
                putUpVo.setIsTop3Tag(putUpArea.getTop3Tag());
                BeanUtils.copyProperties(putUpArea, putUpVo);
                //如果不是规则引用则去查该数据推荐区下的商品
                if (!putUpArea.getGoodsSettingType().equals(MallHomeGroupArea.Enums.IMPORT_RULE.toString())) {
                    List<MallHomeGoods> mallHomeGoodsList = putUpGoodsMap.get(putUpArea.getNo());
                    putUpVo.setGoodsList(getHomeGroupAreaInfoGoods(mallHomeGoodsList, null));
                    putUpAreas.add(putUpVo);
                    continue;
                }
                //规则引用则把规则放入
                HomeGroupAreaInfoVO.ImportRule importRule = new HomeGroupAreaInfoVO.ImportRule();
                String ruleJson = putUpArea.getRuleJson();
                if (StringUtils.isBlank(ruleJson)) {
                    putUpAreas.add(putUpVo);
                    continue;
                }
                MallHomeGroupPutUpArea.ImportRuleDTO importRuleDTO = JSONObject.parseObject(ruleJson, MallHomeGroupPutUpArea.ImportRuleDTO.class);
                BeanUtils.copyProperties(importRuleDTO, importRule);
                putUpVo.setImportRule(importRule);
                putUpAreas.add(putUpVo);
            }
            vo.setPutUpAreaList(putUpAreas);
        }
        //是否开启菜单
        if (groupArea.getIsCate() == EnableEnum.YES.getEnable()) {
            //查询所有菜单
            QueryWrapper<MallHomeGoodsCate> cateQw = new QueryWrapper<>();
            cateQw.lambda().eq(MallHomeGoodsCate::getGroupNo, groupArea.getNo());
            cateQw.lambda().orderByDesc(MallHomeGoodsCate::getIsSticky);
            cateQw.lambda().orderByDesc(MallHomeGoodsCate::getUpdateTime);
            List<MallHomeGoodsCate> cateGoodsList = iMallHomeGoodsCateService.list(cateQw);
            Map<String, String> goodsCateMap = cateGoodsList.stream().collect(Collectors.toMap(MallHomeGoodsCate::getNo, MallHomeGoodsCate::getMenuName));
            List<String> cateGoodsNoList = cateGoodsList.stream().map(MallHomeGoodsCate::getNo).toList();
            //处理菜单下的所有数据
            ArrayList<HomeGroupAreaInfoVO.GoodsMenu> goodsMenus = new ArrayList<>();
            for (MallHomeGoodsCate cateGoods : cateGoodsList) {
                HomeGroupAreaInfoVO.GoodsMenu goodsMenu = new HomeGroupAreaInfoVO.GoodsMenu();
                goodsMenu.setMenuName(cateGoods.getMenuName());
                goodsMenu.setIsSticky(cateGoods.getIsSticky());
                goodsMenu.setIsTop3Sort(cateGoods.getIsTop3Sort());
                goodsMenus.add(goodsMenu);
            }
            vo.setGoodsCateList(goodsMenus);
            //查询菜单下的商品
            QueryWrapper<MallHomeGoods> cateGoodsQw = new QueryWrapper<>();
            cateGoodsQw.lambda().in(MallHomeGoods::getMenuNo, cateGoodsNoList);
            List<MallHomeGoods> goodsList = iMallHomeGroupGoodsService.list(cateGoodsQw);
            List<HomeGroupAreaInfoVO.GoodsInfo> homeGroupAreaInfoGoods = getHomeGroupAreaInfoGoods(goodsList, goodsCateMap);
            vo.setGoodsInfoList(homeGroupAreaInfoGoods);
            return vo;
        }
        //没有开启菜单
        vo.setGoodsCateList(new ArrayList<>());
        //如果不是配置类型不是规则引用
        if (!groupArea.getGoodsSettingType().equals(MallHomeGroupArea.Enums.IMPORT_RULE.toString())) {
            //查询这个聚合区下配置的所有商品
            QueryWrapper<MallHomeGoods> cateGoodsQw = new QueryWrapper<>();
            cateGoodsQw.lambda().in(MallHomeGoods::getHomeGroupNo, groupArea.getNo());
            cateGoodsQw.lambda().isNull(MallHomeGoods::getMenuNo);
            cateGoodsQw.lambda().isNull(MallHomeGoods::getPutUpAreaNo);
            List<MallHomeGoods> goodsList = iMallHomeGroupGoodsService.list(cateGoodsQw);
            List<HomeGroupAreaInfoVO.GoodsInfo> homeGroupAreaInfoGoods = getHomeGroupAreaInfoGoods(goodsList, null);
            vo.setGoodsInfoList(homeGroupAreaInfoGoods);
            return vo;
        }
        //查询规则引用
        String importRuleJson = groupArea.getImportRuleJson();
        if (StringUtils.isBlank(importRuleJson)) {
            return vo;
        }
        //回显规则引用所使用的规则
        MallHomeGroupArea.ImportRuleDTO importRuleDTO = JSONObject.parseObject(importRuleJson, MallHomeGroupArea.ImportRuleDTO.class);
        HomeGroupAreaInfoVO.ImportRule importRule = new HomeGroupAreaInfoVO.ImportRule();
        BeanUtils.copyProperties(importRuleDTO, importRule);
        vo.setImportRule(importRule);
        return vo;

    }


    public List<HomeGroupAreaInfoVO.GoodsInfo> getHomeGroupAreaInfoGoods(List<MallHomeGoods> mallHomeGoodsList, Map<String, String> goodsCateMap) {
        if (CollectionUtils.isEmpty(mallHomeGoodsList)) {
            return new ArrayList<>();
        }
        List<HomeGroupAreaInfoVO.GoodsInfo> goodsInfos = new ArrayList<>();
        for (MallHomeGoods mallHomeGoods : mallHomeGoodsList) {
            HomeGroupAreaInfoVO.GoodsInfo goodsInfo = new HomeGroupAreaInfoVO.GoodsInfo();
            BeanUtils.copyProperties(mallHomeGoods, goodsInfo);
            goodsInfo.setGoodsImg(mallHomeGoods.getGoodsImage());
            goodsInfo.setGoodsBrand(mallHomeGoods.getBrandName());
            goodsInfo.setSendGoodsMethod(mallHomeGoods.getGoodsSendMethod());
            goodsInfo.setGoodsPrice(MoneyUtil.long2Str(mallHomeGoods.getPrice()));
            if (Objects.isNull(goodsCateMap)) {
                goodsInfos.add(goodsInfo);
                continue;
            }
            goodsInfo.setCateName(goodsCateMap.get(mallHomeGoods.getMenuNo()));
            goodsInfos.add(goodsInfo);
        }
        return goodsInfos;
    }


    /**
     * 查询聚合区信息列表
     *
     * @return 聚合区信息列表
     */
    public List<HomeGroupAreaVO> getHomeGroupAreaList() {
        List<MallHomeGroupArea> groupAreas = iMallHomeGroupAreaService.list();
        ArrayList<HomeGroupAreaVO> results = new ArrayList<>();
        for (MallHomeGroupArea groupArea : groupAreas) {
            HomeGroupAreaVO vo = new HomeGroupAreaVO();
            vo.setId(groupArea.getId());
            vo.setTitle(groupArea.getTitle());
            vo.setTitleTag(groupArea.getTitleTag());
            vo.setSubTitle(groupArea.getSubTitle());
            vo.setEmp(groupArea.getEmpName() + " " + groupArea.getEmpPhone());
            vo.setUpdateTime(groupArea.getUpdateTime());
            vo.setStatus(groupArea.getStatus());
            vo.setType(groupArea.getType());
            results.add(vo);
        }
        return results;
    }


    /**
     * 添加推荐区域信息到首页聚合区
     * 此方法遍历给定的推荐区域列表，为每个区域创建相应的推荐区域记录，并保存到数据库
     * 同时，它还处理每个区域内的商品设置，并将这些商品添加到首页聚合区的商品列表中
     *
     * @param putUpAreaList 数据推荐区域列表，包含需要添加到首页聚合的区域信息
     * @param groupNo       首页聚合区唯一键，用于关联推荐区和商品集合
     * @param groupGoods    聚合区商品列表，将添加数据推荐区域内设置的商品到此列表中
     */
    private void addPutUpArea(List<HomeGroupAreaCondition.PutUpArea> putUpAreaList, String groupNo, List<MallHomeGoods> groupGoods) {
        ArrayList<MallHomeGroupPutUpArea> putUpAreas = new ArrayList<>();
        for (HomeGroupAreaCondition.PutUpArea putUpArea : putUpAreaList) {
            MallHomeGroupPutUpArea mallHomeGroupPutUpArea = new MallHomeGroupPutUpArea();
            mallHomeGroupPutUpArea.setTop3Tag(putUpArea.getIsTop3Tag());
            BeanUtils.copyProperties(putUpArea, mallHomeGroupPutUpArea);
            mallHomeGroupPutUpArea.setNo("put_up" + UUID.randomUUID());
            mallHomeGroupPutUpArea.setRuleJson(JSONObject.toJSONString(putUpArea.getImportRule()));
            // 设置首页聚合区id
            mallHomeGroupPutUpArea.setHomeGrepAreaNo(groupNo);
            putUpAreas.add(mallHomeGroupPutUpArea);
            // 处理数据推荐区的商品设置，并将这些商品添加到首页聚合区的商品列表中
            List<MallHomeGoods> mallHomeGoods = putUpAreaGoodsSetting(putUpArea, mallHomeGroupPutUpArea.getNo(), groupNo);
            groupGoods.addAll(mallHomeGoods);
        }
        // 保存推荐区域数据
        iMallHomeGroupPutUpAreaService.saveBatch(putUpAreas);
    }

    /**
     * 保存分类信息
     * 当分类功能禁用时，根据传入的条件和商品分类列表进行保存操作
     *
     * @param con           包含添加或更新条件的对象，用于获取分类列表和其他相关信息
     * @param groupAreaNo   区域唯一键，用于关联分类信息
     * @param goodsCateList 商品分类列表，用于批量保存分类信息
     */
    private void saveCate(HomeGroupAreaCondition.AddOrUpdateHomeGroupAreaCon con, String groupAreaNo, List<MallHomeGoodsCate> goodsCateList) {
        // 如果分类功能被禁用，则直接返回，无需执行后续操作
        if (!con.getIsCate().equals(EnableEnum.YES.getEnable())) {
            return;
        }
        // 遍历商品分类列表，将每个分类的信息复制到新的 MallHomeGroupGoodsCate 对象中，并设置区域ID，然后添加到待保存的列表中
        for (HomeGroupAreaCondition.GoodsMenu goodsMenu : con.getGoodsCateList()) {
            MallHomeGoodsCate mallHomeGoodsCate = new MallHomeGoodsCate();
            BeanUtils.copyProperties(goodsMenu, mallHomeGoodsCate);
            mallHomeGoodsCate.setIsSticky(EnableEnum.YES.getEnable());
            mallHomeGoodsCate.setGroupNo(groupAreaNo);
            mallHomeGoodsCate.setNo("cate" + UUID.randomUUID());
            goodsCateList.add(mallHomeGoodsCate);
        }
        // 如果分类列表为空，则创建一个默认的分类（“全部”），并设置为置顶，然后添加到待保存的列表中
        MallHomeGoodsCate mallHomeGoodsCate = new MallHomeGoodsCate();
        mallHomeGoodsCate.setMenuName("全部");
        mallHomeGoodsCate.setGroupNo(groupAreaNo);
        mallHomeGoodsCate.setIsSticky(EnableEnum.YES.getEnable());
        mallHomeGoodsCate.setNo("cate" + UUID.randomUUID());
        goodsCateList.add(mallHomeGoodsCate);
        // 批量保存商品分类信息
        iMallHomeGoodsCateService.saveBatch(goodsCateList);
    }

    /**
     * 添加商品到指定的首页区域
     * 本函数根据不同的商品设置类型，手动或自动地将商品添加到首页聚合区区域中
     *
     * @param goodsCateList 商品分类列表，用于获取分类ID与分类名称的映射
     * @param con           首页聚合区域条件对象，包含添加或更新首页聚合区域的商品信息
     * @param groupGoods    首页聚合商品列表，用于存储待保存的商品对象
     * @param groupAreaNo   首页聚合区域唯一键，标识特定的首页聚合区域
     */
    private void addGoods(List<MallHomeGoodsCate> goodsCateList, HomeGroupAreaCondition.AddOrUpdateHomeGroupAreaCon con, List<MallHomeGoods> groupGoods, String groupAreaNo) {
        // 将商品分类列表转换为Map，便于后续快速获取分类ID
        Map<String, String> cateMap = goodsCateList.stream().collect(Collectors.toMap(MallHomeGoodsCate::getMenuName, MallHomeGoodsCate::getNo));

        // 根据商品设置类型决定如何添加商品
        if (con.getGoodsSettingType().equals(MallHomeGroupArea.Enums.MANUAL.toString())) {
            // 手动设置商品时，遍历商品信息列表，创建商品对象，并设置分类ID
            for (HomeGroupAreaCondition.GoodsInfo goodsInfo : con.getGoodsInfoList()) {
                MallHomeGoods goods = getMallHomeGroupGoods(goodsInfo);
                //如果穿过来的cateName为空，那么就去查找默认为“全部”的cateName
                String cateId = cateMap.get(StringUtils.isNotBlank(goodsInfo.getCateName()) ? goodsInfo.getCateName() : "全部");
                //如果默认的也没有，那么就设置成groupAreaId
                if (Objects.isNull(cateId)) {
                    goods.setHomeGroupNo(groupAreaNo);
                } else {
                    goods.setHomeGroupNo(groupAreaNo);
                    goods.setMenuNo(cateId);
                }
                goods.setIsMainAreaDis(EnableEnum.YES.getEnable());
                groupGoods.add(goods);
            }
        } else {
            // 自动引入商品时，根据不同的引入规则处理
            HomeGroupAreaCondition.ImportRule importRule = con.getImportRule();
            if (importRule.getType().equals(MallHomeGroupArea.Enums.NEW_LINE.toString())) {
                // 如果是按新品引入规则，获取符合条件的新品列表，并设置团购区域ID
                List<MallHomeGoods> goodsList = getGoodsByNewLineDay(importRule.getDay());
                goodsList.forEach(goods -> goods.setHomeGroupNo(groupAreaNo));
                groupGoods.addAll(goodsList);
            }

        }
        // 最后批量保存所有商品，无论是手动添加还是自动引入的商品
        for (MallHomeGoods groupGood : groupGoods) {
            iMallHomeGroupGoodsService.save(groupGood);
        }
//        iMallHomeGroupGoodsService.saveBatch(groupGoods);
    }

    /**
     * 删除现有的聚合区商品信息，以便后续重新添加
     *
     * @param groupArea 聚合区信息
     */
    private void removeOther(MallHomeGroupArea groupArea) {
        // 准备查询条件以删除现有的推荐区域、分类和商品信息，以便后续重新添加
        QueryWrapper<MallHomeGroupPutUpArea> putUpQw = new QueryWrapper<>();
        putUpQw.lambda().eq(MallHomeGroupPutUpArea::getHomeGrepAreaNo, groupArea.getNo());

        //List<String> putUpAreaNoList = iMallHomeGroupPutUpAreaService.list(putUpQw).stream().map(MallHomeGroupPutUpArea::getNo).toList();


        QueryWrapper<MallHomeGoodsCate> cateQw = new QueryWrapper<>();
        cateQw.lambda().eq(MallHomeGoodsCate::getGroupNo, groupArea.getNo());
        // List<String> cateGoodsNoList = iMallHomeGoodsCateService.list(cateQw).stream().map(MallHomeGoodsCate::getNo).toList();

        // 删除现有的聚合区商品信息，以便后续重新添加
        QueryWrapper<MallHomeGoods> goodsQw = new QueryWrapper<>();
        goodsQw.lambda().eq(MallHomeGoods::getHomeGroupNo, groupArea.getNo());
        iMallHomeGroupGoodsService.remove(goodsQw);
        // 删除现有的分类和推荐区域信息，以便后续重新添加
        iMallHomeGoodsCateService.remove(cateQw);
        iMallHomeGroupPutUpAreaService.remove(putUpQw);
    }

    /**
     * 根据首页分组区域的商品设置类型，配置商品信息
     * 此方法处理不同商品设置类型的逻辑，包括手动设置、单个商品设置和按规则导入商品
     *
     * @param putUpArea 首页分组区域的条件对象，包含商品设置类型和其他相关条件
     * @param putUpNo   分组区域的唯一键，用于关联商品和分组区域
     * @return 返回一个包含配置好的商品信息的列表
     */
    public List<MallHomeGoods> putUpAreaGoodsSetting(HomeGroupAreaCondition.PutUpArea putUpArea, String putUpNo, String groupAreaNo) {
        // 初始化一个空的商品列表，用于存储配置好的商品信息
        List<MallHomeGoods> groupGoods = new ArrayList<>();

        // 当商品设置类型为手动设置时，遍历所有商品信息并配置到商品列表中
        if (putUpArea.getGoodsSettingType().equals(MallHomeGroupArea.Enums.MANUAL.toString())) {
            for (HomeGroupAreaCondition.GoodsInfo goodsInfo : putUpArea.getGoodsList()) {
                // 根据商品信息获取或创建一个商场首页分组商品对象，并设置其分组区域ID
                MallHomeGoods mallHomeGoods = getMallHomeGroupGoods(goodsInfo);
                mallHomeGoods.setPutUpAreaNo(putUpNo);
                mallHomeGoods.setHomeGroupNo(groupAreaNo);
                // 将配置好的商品添加到商品列表中
                groupGoods.add(mallHomeGoods);
            }
        }

        // 当商品设置类型为仅设置一个商品时，检查商品列表中是否只有一个商品
        if (putUpArea.getGoodsSettingType().equals(MallHomeGroupArea.Enums.ONLY_GOODS.toString())) {
            if (putUpArea.getGoodsList().size() > 1) {
                // 如果商品列表中多于一个商品，抛出异常提示只能设置一个商品
                throw new YsException(-1, "该类型只能设置一个商品");
            }
            // 获取商品列表中的唯一商品信息，并配置到商品列表中
            HomeGroupAreaCondition.GoodsInfo goodsInfo = putUpArea.getGoodsList().getFirst();
            MallHomeGoods mallHomeGoods = getMallHomeGroupGoods(goodsInfo);
            mallHomeGoods.setPutUpAreaNo(putUpNo);
            mallHomeGoods.setHomeGroupNo(groupAreaNo);
            groupGoods.add(mallHomeGoods);
        }

        // 当商品设置类型为按规则导入时，根据不同的规则类型获取商品列表并配置
        if (putUpArea.getGoodsSettingType().equals(MallHomeGroupArea.Enums.IMPORT_RULE.toString())) {
            // 如果规则类型为按新上线商品和销量排序，获取符合条件的商品列表
            if (putUpArea.getImportRule().getType().equals(MallHomeGroupPutUpArea.Enums.NEW_LINE_SALE_NUM.toString())) {
                List<MallHomeGoods> goodsList = getGoodsByNewLineDayAndSaleNum(putUpArea.getImportRule().getDay(), putUpArea.getImportRule().getNum());
                // 为每个商品设置分组区域ID，并添加到商品列表中
                goodsList.forEach(goods ->
                {
                    goods.setHomeGroupNo(groupAreaNo);
                    goods.setPutUpAreaNo(putUpNo);
                });
                groupGoods.addAll(goodsList);
            }
            // 如果规则类型为按最近N天销量排序，获取符合条件的商品列表
            if (putUpArea.getImportRule().getType().equals(MallHomeGroupPutUpArea.Enums.N_DAY_SALE_NUM.toString())) {
                List<MallHomeGoods> goodsList = getGoodsByNDayAndSaleNum(putUpArea.getImportRule().getDay(), putUpArea.getImportRule().getNum());
                // 为每个商品设置分组区域ID，并添加到商品列表中
                goodsList.forEach(goods ->
                {
                    goods.setHomeGroupNo(groupAreaNo);
                    goods.setPutUpAreaNo(putUpNo);
                });
                groupGoods.addAll(goodsList);
            }
        }

        // 返回配置好的商品列表
        return groupGoods;
    }

    /**
     * 根据首页组的商品信息创建并返回一个MallHomeGroupGoods对象
     * 此方法用于将从首页组区域条件中获取的商品信息转换为MallHomeGroupGoods对象
     * 它封装了商品的各种属性，如商品ID、品牌名称、图片、名称、价格等
     *
     * @param goodsInfo 商品信息，包含商品的各种属性
     * @return 返回一个填充了商品信息的MallHomeGroupGoods对象
     */
    private MallHomeGoods getMallHomeGroupGoods(HomeGroupAreaCondition.GoodsInfo goodsInfo) {
        // 创建一个MallHomeGroupGoods对象
        MallHomeGoods goods = new MallHomeGoods();

        // 设置商品ID
        goods.setGoodsId(goodsInfo.getGoodsId());
        // 设置品牌名称
        goods.setBrandName(goodsInfo.getBrandName());
        // 设置商品图片URL
        goods.setGoodsImage(goodsInfo.getGoodsImg());
        // 设置商品名称
        goods.setGoodsName(goodsInfo.getGoodsName());
        // 将字符串价格转换为Long类型并设置
        goods.setPrice(MoneyUtil.str2Long(goodsInfo.getGoodsPrice()));
        // 设置优惠折扣
        goods.setYsCoinDiscount(goodsInfo.getYsCoinDiscount());
        // 设置商品配送方式
        goods.setGoodsSendMethod(goodsInfo.getSendGoodsMethod());
        // 设置库存量
        goods.setStock(goodsInfo.getStock());

        // 返回填充好的MallHomeGroupGoods对象
        return goods;
    }


    /**
     * 根据近N天的销售数量获取商品列表
     * 该方法旨在找出在最近N天内销售数量最多的商品，以便进行热门商品推荐或分析
     *
     * @param day 过去的天数，用于确定查询的时间范围
     * @param num 返回的商品数量，用于限制结果集大小
     * @return 返回一个包含热销商品的列表
     */
    public List<MallHomeGoods> getGoodsByNDayAndSaleNum(Integer day, Integer num) {
        // 查询已支付的订单，且订单创建时间在当前时间往前推day天
        QueryWrapper<Order> orderQw = new QueryWrapper<>();
        orderQw.lambda().eq(Order::getOrderStatus, StatusOldEnum.ORDER_PAYED.getStatus());
        orderQw.lambda().ge(Order::getCreateTime, LocalDateTime.now().minusDays(day));
        List<Order> orderList = iOrderService.list(orderQw);
        // 如果没有找到任何订单，直接返回空列表
        if (CollectionUtils.isEmpty(orderList)) {
            new ArrayList<>();
        }
        // 提取订单ID列表，以便后续查询订单商品
        List<Long> orderIdList = orderList.stream().map(Order::getId).toList();
        if (CollectionUtils.isEmpty(orderIdList)) {
            return new ArrayList<>();
        }
        // 查询属于上述订单的商品
        QueryWrapper<OrderGoods> orderGoodsQw = new QueryWrapper<>();
        orderGoodsQw.lambda().in(OrderGoods::getOrderId, orderIdList);
        List<OrderGoods> orderGoodsList = iOrderGoodsService.list(orderGoodsQw);
        // 根据商品销售数量排序并限制结果数量，获取热销商品ID列表
        List<Long> previousGoodsIdList = orderGoodsList.stream()
                .collect(Collectors.groupingBy(OrderGoods::getGoodsId, Collectors.summingInt(OrderGoods::getGoodsCount)))
                .entrySet()
                .stream()
                .sorted((a, b) -> b.getValue() - a.getValue())
                // 按销量倒序
                .map(Map.Entry::getKey)
                // 取出 goodsId
                .toList();
        // 查询热销商品的详细信息
        QueryWrapper<Goods> goodsQw = getGoodsQw();
        goodsQw.lambda().in(Goods::getId, previousGoodsIdList);
        List<Goods> goodsList = iGoodsService.list(goodsQw);
        // 如果没有找到任何商品，直接返回空列表
        if (CollectionUtils.isEmpty(goodsList)) {
            return new ArrayList<>();
        }
        List<MallHomeGoods> groupGoods = getGroupGoods(Stream.concat(
                previousGoodsIdList.stream()
                        .map(id -> goodsList.stream()
                                .filter(g -> g.getId().equals(id))
                                .findFirst()
                                .orElse(null))
                        .filter(Objects::nonNull),
                goodsList.stream()
                        .filter(g -> !previousGoodsIdList.contains(g.getId()))
        ).toList());
        // 将商品列表转换为所需的格式并返回
        return groupGoods.stream().limit(num).toList();
    }


    /**
     * 根据上新时间和销售数量获取商品列表
     * 该方法用于获取在指定天数内上线，并且按销售数量排序的商品列表
     * 主要用途是为首页提供按新品和热销程度排序的商品展示
     *
     * @param day 上新天数，用于筛选在指定天数内上新的商品
     * @param num 返回的商品数量，用于限制结果列表的大小
     * @return 返回一个包含指定数量热销商品的列表，如果无商品则返回空列表
     */
    public List<MallHomeGoods> getGoodsByNewLineDayAndSaleNum(Integer day, Integer num) {
        // 初始化商品查询条件
        QueryWrapper<Goods> goodsQw = getGoodsQw();

        // 筛选在指定天数内上新的商品
        goodsQw.lambda().ge(Goods::getLineTime, LocalDateTime.now().minusDays(day));

        // 按销售数量降序排序
        goodsQw.lambda().orderByDesc(Goods::getRealSaleNum);

        // 查询并获取销售数量前num名的商品
        List<Goods> goodsList = iGoodsService.list(goodsQw);
        if (CollectionUtils.isEmpty(goodsList)) {
            return new ArrayList<>();
        }
        List<Long> goodsIdList = goodsList.stream().map(Goods::getId).toList();

       /* // 查询属于上述订单的商品
        QueryWrapper<OrderGoods> orderGoodsQw = new QueryWrapper<>();
        orderGoodsQw.lambda().in(OrderGoods::getGoodsId, goodsIdList);
        List<OrderGoods> orderGoodsList = iOrderGoodsService.list(orderGoodsQw);

        if (CollectionUtils.isEmpty(orderGoodsList)) {
            return new ArrayList<>();
        }
        List<Long> orderIdList = orderGoodsList.stream().map(OrderGoods::getOrderId).toList();
        QueryWrapper<Order> orderQw = new QueryWrapper<>();
        orderQw.lambda().eq(Order::getOrderStatus, StatusOldEnum.ORDER_PAYED.getStatus());
        orderQw.lambda().in(Order::getId, orderIdList);
        List<Order> orderList = iOrderService.list(orderQw);
        if (CollectionUtils.isEmpty(orderList)) {
            return new ArrayList<>();
        }
        List<Long> orderOrderPayedIdList = orderList.stream().map(Order::getId).toList();
        orderGoodsList = orderGoodsList.stream()
                .filter(orderGoods -> orderOrderPayedIdList.contains(orderGoods.getOrderId()))
                .toList();

        // 根据商品销售数量排序并限制结果数量，获取热销商品ID列表
        List<Long> previousGoodsIdList = orderGoodsList.stream()
                .collect(Collectors.groupingBy(OrderGoods::getGoodsId, Collectors.summingInt(OrderGoods::getGoodsCount)))
                .entrySet()
                .stream()
                .sorted((a, b) -> b.getValue() - a.getValue())
                // 按销量倒序
                .map(Map.Entry::getKey)
                // 取出 goodsId
                .toList();

        List<Goods> goodsListFilter = goodsList.stream().filter(goods -> previousGoodsIdList.contains(goods.getId())).toList();
*/
        // 如果商品列表为空，则返回一个新的空列表
        if (CollectionUtils.isEmpty(goodsList)) {
            return new ArrayList<>();
        }
      /*  List<MallHomeGoods> groupGoods = getGroupGoods(Stream.concat(
                previousGoodsIdList.stream()
                        .map(id -> goodsListFilter.stream()
                                .filter(g -> g.getId().equals(id))
                                .findFirst()
                                .orElse(null))
                        .filter(Objects::nonNull),
                goodsList.stream()
                        .filter(g -> !previousGoodsIdList.contains(g.getId()))).toList());*/
        List<MallHomeGoods> groupGoods = getGroupGoods(goodsList);
        // 将商品列表转换为首页商品分组列表
        return groupGoods.stream().limit(num).toList();

    }


    /**
     * 根据上新时间获取商品列表
     * 该方法用于获取在指定天数内上新的商品，并将其分组返回
     * 主要步骤包括：
     * 1. 构建商品查询条件，查询在指定天数内上新的商品
     * 2. 调用商品服务获取符合条件的商品列表
     * 3. 如果商品列表为空，则返回空列表
     * 4. 否则，将商品列表进行分组处理，并返回分组后的商品列表
     *
     * @param day 指定的天数，用于确定上新时间范围
     * @return 返回分组后的商品列表如果无符合条件的商品，则返回空列表
     */
    public List<MallHomeGoods> getGoodsByNewLineDay(Integer day) {
        // 构建商品查询条件，查询在指定天数内上新的商品
        QueryWrapper<Goods> goodsQw = getGoodsQw();
        goodsQw.lambda().ge(Goods::getLineTime, LocalDateTime.now().minusDays(day));

        // 调用商品服务获取符合条件的商品列表
        List<Goods> goodsList = iGoodsService.list(goodsQw);

        // 如果商品列表为空，则返回空列表
        if (CollectionUtils.isEmpty(goodsList)) {
            return new ArrayList<>();
        }

        // 将商品列表进行分组处理，并返回分组后的商品列表
        return getGroupGoods(goodsList);
    }

    /**
     * 根据商品列表获取分组商品信息
     * 此方法主要用于首页或其他需要展示商品列表的场景，将商品信息进行加工处理，便于展示
     *
     * @param goodsList 商品列表
     * @return 返回加工后的分组商品信息列表
     */
    public List<MallHomeGoods> getGroupGoods(List<Goods> goodsList) {
        ArrayList<MallHomeGoods> groupGoods = new ArrayList<>();
        if (CollectionUtils.isEmpty(goodsList)) {
            return groupGoods;
        }
        //查询配置商品的品牌id
        List<Long> brandIdList = goodsList.stream().map(Goods::getBrandId).toList();
        List<Long> goodsIdList = goodsList.stream().map(Goods::getId).toList();

        //查询商品的所有品牌
        Map<Long, GoodsBrand> brandMap;
        if (CollectionUtils.isEmpty(brandIdList)) {
            brandMap = new HashMap<>();
        } else {
            QueryWrapper<GoodsBrand> goodsBrandQw = new QueryWrapper<>();
            goodsBrandQw.lambda().in(GoodsBrand::getId, brandIdList);
            brandMap = iGoodsBrandService.list(goodsBrandQw).stream().collect(Collectors.toMap(GoodsBrand::getId, Function.identity()));
        }

        //查询商品所有规格，因为在最开始判断过商品id是否为空，所以这里不用判断
        QueryWrapper<GoodsSpecs> goodsSpecsQw = new QueryWrapper<>();
        goodsSpecsQw.lambda().in(GoodsSpecs::getGoodsId, goodsIdList);
        List<GoodsSpecs> goodsSpecsListAll = iGoodsSpecsService.list(goodsSpecsQw);

        //对商品规格集合以商品id进行分组
        Map<Long, List<GoodsSpecs>> goodsSpecsMap = goodsSpecsListAll.stream().collect(Collectors.groupingBy(GoodsSpecs::getGoodsId));
        List<Long> inMallGoodsIdList = iMallHomeGoodsService.list().stream().map(MallHomeGoods::getGoodsId).toList();
        for (Goods goods : goodsList) {
            if (inMallGoodsIdList.contains(goods.getId())) {
                continue;
            }
            MallHomeGoods goodsInfo = new MallHomeGoods();
            goodsInfo.setIsMainAreaDis(EnableEnum.YES.getEnable());
            goodsInfo.setGoodsId(goods.getId());
            goodsInfo.setGoodsImage(goods.getGoodsBannerList().getFirst());
            goodsInfo.setGoodsName(goods.getGoodsName());
            goodsInfo.setPrice(goods.getGoodsPrice());
            //计算并赋值幺币抵扣率
            List<GoodsSpecs> goodsSpecsList = goodsSpecsMap.get(goods.getId());
            String ysCoinRange;
            if (goodsSpecsList.size() == 1) {
                GoodsSpecs goodsSpecs = goodsSpecsList.getFirst();
                ysCoinRange = String.valueOf(goodsSpecs.getYsCoinDiscount());
            } else {
                Map<String, String> ysCoinRangeMap = GoodsSpecs.getYsCoinRange(goodsSpecsList);
                ysCoinRange = ysCoinRangeMap.get("minYsCoinDiscount") + "~" + ysCoinRangeMap.get("maxYsCoinDiscount");
            }
            Set<String> sendGoods = new HashSet<>();
            for (GoodsSpecs goodsSpecs : goodsSpecsList) {
                sendGoods.add(goodsSpecs.getSendGoodsType());
            }
            if (com.alibaba.nacos.common.utils.CollectionUtils.isNotEmpty(sendGoods)) {
                StringBuilder send = new StringBuilder();
                for (String sendGoodsType : sendGoods) {
                    send.append(sendGoodsType).append(",");
                }
                goodsInfo.setGoodsSendMethod(send.substring(0, send.length() - 1));
            }
            goodsInfo.setYsCoinDiscount(ysCoinRange);
            //计算商品所剩余库存
            long stockTotal = goodsSpecsList.stream().mapToLong(GoodsSpecs::getStock).sum();
            goodsInfo.setStock((int) stockTotal);

            //处理品牌信息
            if (Objects.isNull(goods.getBrandId())) {
                groupGoods.add(goodsInfo);
                continue;
            }
            GoodsBrand goodsBrand = brandMap.get(goods.getBrandId());
            if (Objects.isNull(goodsBrand)) {
                groupGoods.add(goodsInfo);
                continue;
            }
            goodsInfo.setBrandName(goodsBrand.getBrandName());

            groupGoods.add(goodsInfo);
        }
        return groupGoods;
    }

    private QueryWrapper<Goods> getGoodsQw() {
        QueryWrapper<Goods> goodsQw = new QueryWrapper<>();
        goodsQw.lambda().eq(Goods::getIsDelete, EnableEnum.NO.getEnable());
        goodsQw.lambda().eq(Goods::getIsLine, EnableEnum.YES.getEnable());
        return goodsQw;
    }


}
